const { SUCCESS } = require("./common/constants");
const { toLog, EOL } = require("./common/common");
const moment = require('moment');
const fs = require('fs');
const path = require('path');
const libcu = require("libcu");
const nthfile = require('nth-file');
//AvenirSQL导出功能实现
class Dump {
    constructor() {

    }

    //导出整个数据库
    async dumpDatabase() {

    }

    //导出某个表结构
    async dumpTable(tableName, database, sqlParser, sign) {
        let data = '';
        try {
            await db.select(sqlParser, sign, false);
        } catch (error) {
            data = error;
        }
        //不成功就报错
        if (data.code !== SUCCESS) {
            throw (data);
        }
        toLog("data = ", data.data);
        //取值
        data = data.data;
        let names = await db.getFileNames(database, tableName, true);
        let tableFile = names.tableFile;
        let tableDefine = await db.getTableDefine(tableName, tableFile, database, false);
        toLog("tableDefine = ", tableDefine.table);
        let table = tableDefine.table;
        let columns = '';
        let insertColumns = '';
        for (let key in table) {
            let text = '';
            text += ` ${key} `; //先把列名字加上
            //加上数据类型和长度
            if (table[key].len != '') {
                text += ` ${table[key].type}(${table[key].len}) `
            } else {
                text += ` ${table[key].type}`;
            }
            if (table[key].key) {
                text += ' primary key ';
            }

            if (table[key].not !== null) {
                text += ` not ${table[key].not}`;
            }
            text += ',';
            insertColumns += key + ','
            columns += text;
        }
        let tableDetail = await db.getTableKeyAndNum(tableDefine, tableName, database, false);
        let num = tableDetail.num;
        insertColumns = insertColumns.slice(0, insertColumns.length - 1);
        toLog("insertColumns = ", insertColumns);

        let createSql = `create table ${database}.${tableName} (${columns})`;
        toLog('createSql = ', createSql);
        let sqlFile = '';
        toLog("ini.dump.notForce = ", ini.dump.notForce);
        if (ini.dump.notForce != true) {
            let dropSql = `drop table ${database}.${tableName}`;
            sqlFile += dropSql + EOL;
        }
        sqlFile = createSql + EOL;
        //然后开始组插入的SQL

        for (let i = 0; i < data.length; i++) {
            let insertValues = '';
            let count = 0;
            for (let key in data[i]) {
                count++;
                if (tableDefine.table[key].type === 'number') {
                    insertValues += data[i][key];
                } else {
                    insertValues += `'${data[i][key]}'`;
                }
                if (count < num) {
                    insertValues += ',';
                }
            }
            let insert = `insert into ${database}.${tableName} (${insertColumns}) values(${insertValues})`;
            sqlFile += insert + EOL;
        }
        toLog('sqlFile = ', sqlFile);
        let dumpFileName = `dumpTable_${database}_${tableName}_${moment().format("YYYYMMDDHHmmss")}.sql`;
        let dumpPath = ini.dump.path || './dump';
        if (!fs.existsSync(dumpPath)) {
            fs.mkdirSync(dumpPath);
        }
        try {
            fs.writeFileSync(dumpPath + '/' + dumpFileName, sqlFile);
            log.log(`导出表${tableName}成功`);
            throw (SUCCESS);
        } catch (error) {
            if (error == SUCCESS) {
                throw (error);
            }
            trace.setLog('导出表失败 error->', error);
            throw ("error");
        }

    }

    //展示导出的文件名
    async showDumpList() {
        let dumpPath = ini.dump.path;
        let res = await libcu.cf.walkFolder(dumpPath);
        toLog("res = ",res);
        let data = [];
        for(let i=0;i<res.fileList.length;i++) {
            data.push(path.basename(res.fileList[i]));
        }
        throw({
            code:SUCCESS,
            data,
        })
    }


    //执行SQL语句
    async exec(fileName,sign) {
        //这里注意文件名有没有路径 如果没有则赋值配置文件的默认路径
        if(path.basename(fileName) === fileName) {
            fileName = path.join(ini.dump.path || './dump',fileName);
        }
        if(!fs.existsSync(fileName)) {
            throw("SQLFILE_NOT_FOUND");
        }
        let lines = nthfile.getFileArr(fileName);
        toLog('lines = ',lines);
        for(let i= 0;i<lines.length;i++) {
            try {
                await sql.parse(lines[i],sign);
                trace.setLog(`批处理成功`);
            } catch (error) {
                error === SUCCESS || trace.setLog(`批处理${fileName}的SQL失败,error->${error}`);
            }
        }
        throw(SUCCESS);
    }
}

module.exports = Dump;
